Imports System
Imports System.ComponentModel
Imports System.Drawing
Imports System.Runtime.InteropServices
Imports System.Windows.Forms
Imports DevExpress.CodeRush.Core
Imports DevExpress.CodeRush.PlugInCore
Imports DevExpress.CodeRush.StructuralParser
Imports System.Data
Imports System.Collections
Imports MindFusion.Diagramming
Imports MindFusion.Diagramming.Layout
Imports MindFusion.Diagramming.WinForms
Imports MindFusion.Layout
Imports Pen = MindFusion.Drawing.Pen
Imports SolidBrush = MindFusion.Drawing.SolidBrush

Namespace CR_InheritanceView
    ''' <summary>
    ''' Summary description for InheritanceViewWindow.
    ''' </summary>
    <Guid("5d65b3c2-6beb-4772-9d26-bb47b896c1c4"), _
     Title("Inheritance View")> _
    Public Class InheritanceViewWindow
        Inherits ToolWindowPlugIn

#Region " private fields... "
        Friend WithEvents events_ As DevExpress.DXCore.PlugInCore.DXCoreEvents
        ''' <summary>
        ''' Required designer variable.
        ''' </summary>
        Private components As System.ComponentModel.IContainer
#End Region

        ' constructor...
#Region " InheritanceViewWindow "
        Public Sub New()
            ' This call is required by the Windows.Forms Form Designer.
            InitializeComponent()
        End Sub
#End Region

        ' DXCore-generated code
#Region " InitializePlugIn "
        Public Overrides Sub InitializePlugIn()
            MyBase.InitializePlugIn()

            '
            ' TODO: Add your initialization code here.
            '
        End Sub
#End Region
#Region " FinalizePlugIn "
        Public Overrides Sub FinalizePlugIn()
            '
            ' TODO: Add your finalization code here.
            '

            MyBase.FinalizePlugIn()
        End Sub
#End Region

#Region " ShowWindow "
        ''' <summary>
        ''' Opens and displays this tool window. If the tool window is already open,
        ''' it will be focused.
        ''' </summary>
        Public Shared Function ShowWindow() As EnvDTE.Window
            Return DevExpress.CodeRush.Core.CodeRush.ToolWindows.Show(GetType(InheritanceViewWindow).GUID)
        End Function
#End Region
#Region " HideWindow "
        ''' <summary>
        ''' Hides this tool window if it is open.
        ''' </summary>
        Public Shared Function HideWindow() As EnvDTE.Window
            Return DevExpress.CodeRush.Core.CodeRush.ToolWindows.Hide(GetType(InheritanceViewWindow).GUID)
        End Function
#End Region

#Region " Instance "
        ''' <summary>
        ''' Returns the created instance of this tool window if it is open. If the tool window
        ''' is not open in Visual Studio, this property returns null.
        ''' </summary>
        Public Shared ReadOnly Property Instance() As InheritanceViewWindow
            Get
                Return CType(DevExpress.CodeRush.Core.CodeRush.ToolWindows.GetPlugInControl(GetType(InheritanceViewWindow)), InheritanceViewWindow)
            End Get
        End Property
#End Region

#Region " Component Designer generated code "
        ''' <summary>
        ''' Required method for Designer support - do not modify
        ''' the contents of this method with the code editor.
        ''' </summary>
        Friend WithEvents btnRefresh As System.Windows.Forms.Button
        Friend WithEvents DiagramView As MindFusion.Diagramming.WinForms.DiagramView
        Friend WithEvents Diagram1 As MindFusion.Diagramming.Diagram
        Friend WithEvents TabControl1 As System.Windows.Forms.TabControl
        Friend WithEvents tabAncestor As System.Windows.Forms.TabPage
        Friend WithEvents tabDescendants As System.Windows.Forms.TabPage
        Friend WithEvents DiagramView1 As MindFusion.Diagramming.WinForms.DiagramView
        Friend WithEvents Diagram2 As MindFusion.Diagramming.Diagram

        Private Sub InitializeComponent()
            Me.components = New System.ComponentModel.Container
            Dim resources As System.Resources.ResourceManager = New System.Resources.ResourceManager(GetType(InheritanceViewWindow))
            Me.events_ = New DevExpress.DXCore.PlugInCore.DXCoreEvents(Me.components)
            Me.btnRefresh = New System.Windows.Forms.Button
            Me.DiagramView = New MindFusion.Diagramming.WinForms.DiagramView
            Me.Diagram1 = New MindFusion.Diagramming.Diagram
            Me.TabControl1 = New System.Windows.Forms.TabControl
            Me.tabAncestor = New System.Windows.Forms.TabPage
            Me.tabDescendants = New System.Windows.Forms.TabPage
            Me.DiagramView1 = New MindFusion.Diagramming.WinForms.DiagramView
            Me.Diagram2 = New MindFusion.Diagramming.Diagram
            CType(Me.events_, System.ComponentModel.ISupportInitialize).BeginInit()
            Me.TabControl1.SuspendLayout()
            Me.tabAncestor.SuspendLayout()
            Me.tabDescendants.SuspendLayout()
            CType(Me, System.ComponentModel.ISupportInitialize).BeginInit()
            Me.SuspendLayout()
            '
            'btnRefresh
            '
            Me.btnRefresh.Image = CType(resources.GetObject("btnRefresh.Image"), System.Drawing.Image)
            Me.btnRefresh.Location = New System.Drawing.Point(8, 8)
            Me.btnRefresh.Name = "btnRefresh"
            Me.btnRefresh.Size = New System.Drawing.Size(40, 23)
            Me.btnRefresh.TabIndex = 0
            '
            'DiagramView
            '
            Me.DiagramView.Diagram = Me.Diagram1
            Me.DiagramView.Dock = System.Windows.Forms.DockStyle.Fill
            Me.DiagramView.InplaceEditFont = New System.Drawing.Font("Microsoft Sans Serif", 8.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
            Me.DiagramView.Location = New System.Drawing.Point(0, 0)
            Me.DiagramView.Name = "DiagramView"
            Me.DiagramView.Size = New System.Drawing.Size(272, 246)
            Me.DiagramView.TabIndex = 1
            Me.DiagramView.Text = "DiagramView1"
            '
            'TabControl1
            '
            Me.TabControl1.Anchor = CType((((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom) _
                        Or System.Windows.Forms.AnchorStyles.Left) _
                        Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
            Me.TabControl1.Controls.Add(Me.tabAncestor)
            Me.TabControl1.Controls.Add(Me.tabDescendants)
            Me.TabControl1.Location = New System.Drawing.Point(8, 40)
            Me.TabControl1.Name = "TabControl1"
            Me.TabControl1.SelectedIndex = 0
            Me.TabControl1.Size = New System.Drawing.Size(280, 272)
            Me.TabControl1.TabIndex = 2
            '
            'tabAncestor
            '
            Me.tabAncestor.Controls.Add(Me.DiagramView)
            Me.tabAncestor.Location = New System.Drawing.Point(4, 22)
            Me.tabAncestor.Name = "tabAncestor"
            Me.tabAncestor.Size = New System.Drawing.Size(272, 246)
            Me.tabAncestor.TabIndex = 0
            Me.tabAncestor.Text = "Ancestors"
            '
            'tabDescendants
            '
            Me.tabDescendants.Controls.Add(Me.DiagramView1)
            Me.tabDescendants.Location = New System.Drawing.Point(4, 22)
            Me.tabDescendants.Name = "tabDescendants"
            Me.tabDescendants.Size = New System.Drawing.Size(272, 246)
            Me.tabDescendants.TabIndex = 1
            Me.tabDescendants.Text = "Descendants"
            '
            'DiagramView1
            '
            Me.DiagramView1.Diagram = Me.Diagram2
            Me.DiagramView1.Dock = System.Windows.Forms.DockStyle.Fill
            Me.DiagramView1.InplaceEditFont = New System.Drawing.Font("Microsoft Sans Serif", 8.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
            Me.DiagramView1.Location = New System.Drawing.Point(0, 0)
            Me.DiagramView1.Name = "DiagramView1"
            Me.DiagramView1.Size = New System.Drawing.Size(272, 246)
            Me.DiagramView1.TabIndex = 0
            Me.DiagramView1.Text = "DiagramView1"
            '
            'InheritanceViewWindow
            '
            Me.Controls.Add(Me.TabControl1)
            Me.Controls.Add(Me.btnRefresh)
            Me.Image = CType(resources.GetObject("$this.Image"), System.Drawing.Bitmap)
            Me.ImageBackColor = System.Drawing.Color.FromArgb(CType(0, Byte), CType(255, Byte), CType(255, Byte), CType(255, Byte))
            Me.Name = "InheritanceViewWindow"
            Me.Size = New System.Drawing.Size(296, 320)
            CType(Me.events_, System.ComponentModel.ISupportInitialize).EndInit()
            Me.TabControl1.ResumeLayout(False)
            Me.tabAncestor.ResumeLayout(False)
            Me.tabDescendants.ResumeLayout(False)
            CType(Me, System.ComponentModel.ISupportInitialize).EndInit()
            Me.ResumeLayout(False)

        End Sub
#End Region

        ' protected methods...
#Region " Dispose "
        ''' <summary>
        ''' Clean up any resources being used.
        ''' </summary>
        Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
            If (disposing) Then
                If Not components Is Nothing Then
                    components.Dispose()
                End If
            End If

            MyBase.Dispose(disposing)
        End Sub
#End Region

        Private _dsTree As New DataSet
        Private _htElements As New Hashtable

        Private Sub CreateDataset()
            _dsTree = New DataSet
            Dim dt As DataTable = _dsTree.Tables.Add("Inheritance")
            dt.Columns.Add("ID", GetType(String))
            dt.Columns.Add("ParentID", GetType(String))
            dt.Columns.Add("ChildID", GetType(String))
            dt.Columns.Add("Name", GetType(String))
            dt.Columns.Add("IsInterface", GetType(Boolean))
        End Sub

        Private Sub ShowResult()

        End Sub

        Private Sub GetLevelDown(ByVal theClass As IClassElement, ByVal ID As String)
            Dim DecElement As IElement
            Dim dr As DataRow
            If Not theClass.PrimaryAncestor Is Nothing Then
                DecElement = theClass.PrimaryAncestor.GetDeclaration
                dr = _dsTree.Tables(0).NewRow
                dr("ID") = Guid.NewGuid.ToString
                dr("ParentID") = ID
                If DecElement Is Nothing Then
                    DecElement = ResolveType(theClass.PrimaryAncestor)
                End If
                If DecElement Is Nothing Then
                    Return
                End If
                dr("Name") = DecElement.FullName
                _dsTree.Tables(0).Rows.Add(dr)
                If TypeOf DecElement Is IInterfaceElement Then
                    dr("IsInterface") = True
                    GetLevelDown(DirectCast(DecElement, IInterfaceElement), dr("ID"))
                Else
                    dr("IsInterface") = False
                    GetLevelDown(DirectCast(DecElement, IClassElement), dr("ID"))
                End If
            End If
            If theClass.SecondaryAncestors.Count > 0 Then
                For Each item As ITypeReferenceExpression In theClass.SecondaryAncestors
                    DecElement = item.GetDeclaration
                    dr = _dsTree.Tables(0).NewRow
                    dr("ID") = Guid.NewGuid.ToString
                    dr("ParentID") = ID
                    If DecElement Is Nothing Then
                        DecElement = ResolveType(theClass.PrimaryAncestor)
                    End If
                    If DecElement Is Nothing Then
                        Return
                    End If
                    dr("Name") = DecElement.FullName
                    _dsTree.Tables(0).Rows.Add(dr)
                    dr("IsInterface") = True
                    GetLevelDown(DirectCast(DecElement, IInterfaceElement), dr("ID"))
                Next
            End If
        End Sub

        Private Sub GetLevelDown(ByVal theInterface As IInterfaceElement, ByVal ID As String)
            If Not theInterface.PrimaryAncestor Is Nothing Then
                Dim dr As DataRow = _dsTree.Tables(0).NewRow
                dr("ID") = Guid.NewGuid.ToString
                dr("ParentID") = ID
                Dim DecElement As IElement = theInterface.PrimaryAncestor.GetDeclaration
                If DecElement Is Nothing Then
                    DecElement = ResolveType(theInterface.PrimaryAncestor)
                End If
                If DecElement Is Nothing Then
                    Return
                End If
                dr("Name") = DecElement.FullName
                dr("IsInterface") = True
                _dsTree.Tables(0).Rows.Add(dr)
                GetLevelDown(DirectCast(DecElement, IInterfaceElement), dr("ID"))
            End If
        End Sub

        Private Sub GetLevelUp(ByVal theclass As [Class], ByVal id As String)
            Dim descElements As ITypeElement() = theclass.GetDescendants
            For Each typeClass As ITypeElement In descElements
                Dim dr As DataRow = _dsTree.Tables(0).NewRow
                dr("ID") = Guid.NewGuid.ToString
                dr("ChildID") = id
                dr("Name") = typeClass.FullName
                dr("IsInterface") = TypeOf typeClass Is IInterfaceElement
                _dsTree.Tables(0).Rows.Add(dr)
                GetLevelUp(typeClass.ToLanguageElement, dr("ID"))
            Next
        End Sub

        Private Sub btnRefresh_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnRefresh.Click
            Try
                Dim saveCursor As Cursor = Cursor.Current
                Try
                    Cursor.Current = Cursors.WaitCursor
                    Diagram1.ClearAll()
                    Diagram2.ClearAll()
                    If Not TypeOf CodeRush.Source.Active Is [Class] Then
                        Return
                    End If
                    _htElements.Clear()
                    CreateDataset()
                    Dim theClass As [Class] = DirectCast(CodeRush.Source.Active, [Class])
                    Dim Id As String
                    Id = Guid.NewGuid.ToString
                    Dim dr As DataRow
                    dr = _dsTree.Tables(0).NewRow
                    dr("ID") = Id
                    dr("Name") = theClass.FullName
                    dr("IsInterface") = TypeOf theClass Is IInterfaceElement
                    _dsTree.Tables(0).Rows.Add(dr)
                    GetLevelDown(theClass, Id)

                    Id = Guid.NewGuid.ToString
                    dr = _dsTree.Tables(0).NewRow
                    dr("ID") = Id
                    dr("Name") = theClass.FullName
                    dr("IsInterface") = TypeOf theClass Is IInterfaceElement
                    _dsTree.Tables(0).Rows.Add(dr)
                    GetLevelUp(theClass, Id)
                    Populate(_dsTree)
                Finally
                    Cursor.Current = saveCursor
                End Try
            Catch ex As Exception
                MessageBox.Show(ex.ToString)
            End Try
        End Sub

        Private _shapes As New Hashtable
        Public Sub Populate(ByVal ds As DataSet)
            Dim rootnode As DiagramNode
            _shapes.Clear()
            CreateShapes(ds)
            CreateConnections(ds)
            DoLayout()
        End Sub

        Private Function CreateShapes(ByVal ds As DataSet) As DiagramNode
            For i As Integer = ds.Tables(0).Rows.Count - 1 To 0 Step -1
                Dim name As String = String.Empty
                Dim text As String
                Dim dr As DataRow
                dr = ds.Tables(0).Rows(i)
                name = dr("ID")
                text = dr("Name")
                Dim thenode As DiagramNode
                If Convert.IsDBNull(dr("ChildID")) AndAlso Convert.IsDBNull(dr("ParentID")) Then
                    If i = 0 Then
                        thenode = AddShape(True, name, text, i, Nothing, dr("IsInterface"), True)
                    Else
                        thenode = AddShape(True, name, text, i, Nothing, dr("IsInterface"), False)
                    End If
                Else
                    thenode = AddShape(i = 0, name, text, i, Nothing, dr("IsInterface"), Convert.IsDBNull(dr("ChildID")))
                End If

            Next

        End Function
        Private Sub DoLayout()

            'Diagram1.RoutingOptions.Anchoring = Anchoring.Ignore

            'Dim flowLayout As New MindFusion.Diagramming.Layout.TreeLayout
            'flowLayout.Direction=TreeLayoutDirection.LeftToRight
            'flowLayout.LinkStyle=TreeLayoutLinkType.Rounded
            'flowLayout.Margins = SizeF.Empty
            'flowLayout.Arrange(Diagram1)

            'flowLayout.NodeDistance = 20
            'flowLayout.Margins = SizeF.Empty

            'flowLayout.Arrange(Diagram1)
            Dim tl As New TreeLayout

            tl.Root = Nothing   ' automatically select root
            tl.Type = TreeLayoutType.Cascading
            tl.Direction = TreeLayoutDirection.LeftToRight
            tl.LinkStyle = TreeLayoutLinkType.Cascading2
            tl.LevelDistance = -6   ' this makes node horizontal positions overlap
            tl.NodeDistance = 5
            tl.KeepRootPosition = False  ' leave the root node where it is
            tl.ReversedLinks = False   ' arrows point from parent to child
            tl.Arrange(Diagram1)
            Diagram1.ResizeToFitItems(5)
            tl.Arrange(Diagram2)
            Diagram2.ResizeToFitItems(5)

        End Sub

        Private Sub CreateConnections(ByVal ds As DataSet)
            For i As Integer = 1 To ds.Tables(0).Rows.Count - 1
                Dim shape1 As DiagramNode
                Dim shape2 As DiagramNode
                Dim dr As DataRow
                dr = ds.Tables(0).Rows(i)
                If Convert.IsDBNull(dr("ParentID")) Then
                    If Not Convert.IsDBNull(dr("ChildID")) Then
                        shape1 = _shapes(dr("ID"))
                        shape2 = _shapes(dr("ChildID"))
                        CreateLink(shape2, shape1, "", False, False)
                    End If
                Else
                    shape1 = _shapes(dr("ParentID"))
                    shape2 = _shapes(dr("ID"))
                    CreateLink(shape1, shape2, "", False, True)
                End If

                'Me.DiagramControl1.Layout(LayoutType.Balloon)
            Next
        End Sub

        Private Function CreateLink(ByVal origin As DiagramNode, ByVal destination As DiagramNode, ByVal logicID As String, ByVal up As Boolean, ByVal isAncestor As Boolean) As DiagramLink
            Return CreateLink(origin, destination, logicID, "", up, isAncestor)
        End Function

        Private Function CreateLink(ByVal origin As DiagramNode, ByVal destination As DiagramNode, ByVal logicID As String, ByVal label As String, ByVal up As Boolean, ByVal isAncestor As Boolean) As DiagramLink
            Dim link As DiagramLink
            If isAncestor Then
                link = Diagram1.Factory.CreateDiagramLink(origin, destination)
            Else
                link = Diagram2.Factory.CreateDiagramLink(origin, destination)
            End If
            link.LayoutTraits(FlowLayoutTraits.LogicID) = logicID
            link.Text = logicID
            'If up Then
            '    link.Brush = New SolidBrush(GetColor(callGraphColor.ArrowUp))
            '    link.Pen = New Pen(GetColor(callGraphColor.ArrowUp))
            '    link.HeadPen = New Pen(GetColor(callGraphColor.ArrowUp))
            'Else
            '    link.Brush = New SolidBrush(GetColor(callGraphColor.ArrowDown))
            '    link.Pen = New Pen(GetColor(callGraphColor.ArrowDown))
            '    link.HeadPen = New Pen(GetColor(callGraphColor.ArrowDown))
            'End If
            link.HeadShape = ArrowHead.None
            link.Text = label
            link.ShadowOffsetX = 0
            link.ShadowOffsetY = 0
            link.TextStyle = LinkTextStyle.OverLongestSegment
            link.AllowMoveEnd = False
            link.AllowMoveStart = False
            link.Weight = 1
            ''link.Text += " " + diagram.Links.Count.ToString()

            Return link
        End Function
        Private Function AddShape(ByVal isRootNode As Boolean, ByVal name As String, ByVal text As String, ByVal offset As Integer, ByVal theElement As IElement, ByVal isInterface As Boolean, ByVal IsAncestor As Boolean) As DiagramNode
            Dim myshape As DiagramNode
            myshape = CreateNode(isRootNode, text, MindFusion.Diagramming.Shape.FromId("Rectangle"), isInterface, IsAncestor)
            _shapes.Add(name, myshape)
            Return myshape
        End Function

        Private Function CreateNode(ByVal isRootNode As Boolean, ByVal label As String, ByVal shape As MindFusion.Diagramming.Shape, ByVal isInterface As Boolean, ByVal IsAncestor As Boolean) As DiagramNode
            Dim position As New PointF(1, 1)
            Dim Size As New SizeF(80, 15)

            Dim node As ShapeNode
            If IsAncestor Then
                node = Diagram1.Factory.CreateShapeNode(position, Size, shape)
            Else
                node = Diagram2.Factory.CreateShapeNode(position, Size, shape)
            End If

            node.Text = label
            If Not isRootNode Then
                If isInterface Then
                    node.Brush = New SolidBrush(Color.Yellow)
                    node.TextColor = Color.Blue
                Else
                    node.Brush = New SolidBrush(Color.LightGreen)
                    node.TextColor = Color.Black
                End If
            Else
                node.Brush = New SolidBrush(Color.Blue)
                node.TextColor = Color.Yellow
            End If
            node.Pen = New Pen(Color.Black)
            node.TextFormat.Alignment = StringAlignment.Center
            node.ResizeToFitText(FitSize.KeepRatio)
            node.ZTop()
            Return node
        End Function

        Private Function GetElementType(ByVal element As IElement) As String
            Dim typeElement As IElement = ResolveType(element)
            If TypeOf typeElement Is TypeReferenceExpression Then
                Return DirectCast(typeElement, TypeReferenceExpression).FullSignature
            End If
            If Not (TypeOf typeElement Is ITypeElement) Then
                Return "System.Object"
            End If

            Dim type As ITypeElement = DirectCast(typeElement, ITypeElement)

            If type.IsGeneric Then
                Dim result As String = String.Empty
                Dim propertyName As String = GetIndexedPropertyName(type)
                If Not propertyName Is Nothing AndAlso propertyName <> "" Then
                    result = GetHardCodedType(element, propertyName)
                    If Not result Is Nothing AndAlso result <> "" Then
                        Return result
                    End If
                End If
                result = GetGenericType(element)
                If Not result Is Nothing AndAlso result <> "" Then
                    Return result
                End If
            Else
                Return CodeRush.Strings.[Get]("EnumerableType", type.FullName)
            End If
            Return ""
        End Function
        Private Function GetIndexedPropertyName(ByVal type As ITypeElement) As String
            Dim members As IMemberElementCollection = type.Members
            Dim propertyName As String = [String].Empty
            For Each member As IMemberElement In members
                Dim [property] As IPropertyElement '= TryCast(member, IPropertyElement) 
                If TypeOf member Is IPropertyElement Then
                    [property] = DirectCast(member, IPropertyElement)
                End If
                If Not [property] Is Nothing AndAlso [property].IsIndexed Then
                    propertyName = [property].Name
                    Exit For
                End If
            Next
            Return propertyName
        End Function

        Private Function GetHardCodedType(ByVal element As IElement, ByVal propertyName As String) As String
            Dim type As ITypeElement = DirectCast(ResolveType(element), ITypeElement)
            Dim typeName As String = type.FullName
            If typeName Is Nothing Then
                Return [String].Empty
            End If
            If typeName = "System.Collections.Hashtable" Then
                If propertyName = "Keys" Then
                    Return "DictionaryEntry"
                End If
            ElseIf typeName = "System.Collections.Generic.IDictionary`2" _
            OrElse typeName = "System.Collections.Generic.Dictionary`2" Then
                Dim declaration As IElement = CodeRush.Source.GetDeclaration(element)
                If Not declaration Is Nothing AndAlso (TypeOf declaration Is IHasType) Then
                    Dim typeReference As ITypeReferenceExpression = DirectCast(declaration, IHasType).Type
                    If typeReference Is Nothing Then
                        Return String.Empty
                    End If
                    If TypeOf typeReference Is IGenericExpression Then
                        Dim keyValuePairRef As New TypeReferenceExpression("KeyValuePair")
                        keyValuePairRef.TypeArguments.AddRange(DirectCast(typeReference, IGenericExpression).TypeArguments)
                        Return CodeRush.Language.GenerateExpressionCode(keyValuePairRef)
                    End If
                End If
            End If
            Return [String].Empty
        End Function
        Private Function GetGenericType(ByVal element As IElement) As String
            Dim typeReference As ITypeReferenceExpression = Nothing
            If TypeOf element Is ITypeReferenceExpression Then
                typeReference = DirectCast(element, ITypeReferenceExpression)
            Else
                Dim declaration As IElement = CodeRush.Source.GetDeclaration(element)
                If Not declaration Is Nothing AndAlso (TypeOf declaration Is IHasType) Then
                    typeReference = DirectCast(declaration, IHasType).Type
                End If
            End If
            If typeReference Is Nothing Then
                Return String.Empty
            End If

            Dim arguments As ITypeReferenceExpressionCollection = DirectCast(typeReference, IGenericExpression).TypeArguments
            If Not arguments Is Nothing AndAlso arguments.Count > 0 Then
                Dim arg As ITypeReferenceExpression = DirectCast(arguments(0), ITypeReferenceExpression)
                Dim typeRefExp As TypeReferenceExpression = SourceModelUtils.CreateTypeReferenceExpression(arg)
                Return CodeRush.Language.GenerateExpressionCode(typeRefExp)
            End If
            Return String.Empty
        End Function

        Private Function ResolveType(ByVal active As IElement) As IElement
            Dim resolver As ISourceTreeResolver = ParserServices.SourceTreeResolver
            If TypeOf active Is IMemberElement Then
                Return resolver.ResolveElementType(active)
            End If

            Dim expression As IExpression '= TryCast(active, IExpression) 
            If TypeOf active Is IExpression Then
                expression = DirectCast(active, IExpression)
            End If

            If Not expression Is Nothing Then
                Return resolver.ResolveExpression(expression)
            End If

            Return Nothing
        End Function

    End Class
End Namespace